package org.simple.framework.data.query;

import org.simple.framework.data.annotation.OrderProperty;
import org.simple.framework.data.annotation.QueryClass;
import org.simple.framework.data.entity.Identifiable;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 项目名称：simple-framework
 * 类名称：QuerySpecification
 * 类描述：QuerySpecification
 * 创建时间：2018/9/6
 *
 * @author sisyphus   (E-mail:1620657419@qq.com)
 * @version v1.0
 */
public abstract class QuerySpecification<T extends Identifiable> {

    private BaseQuery query;

    public QuerySpecification(BaseQuery query) {
        this.query = query;
    }

    private static Map<Class<?>, List<OrderProperty>> orderCache = new ConcurrentReferenceHashMap<>();

    protected Junction getClassJunction() {
        Junction result;
        if (query.getClass().isAnnotationPresent(QueryClass.class)) {
            result = query.getClass().getAnnotation(QueryClass.class).junction();
        } else {
            result = Junction.AND;
        }
        return result;
    }

    protected List<Order> getClassOrders() {
        if (orderCache.get(query.getClass()) == null) {
            List<OrderProperty> orderProperties = new ArrayList<>();
            if (query.getClass().isAnnotationPresent(QueryClass.class)) {
                OrderProperty[] orders = query.getClass().getAnnotation(QueryClass.class).orders();
                if (orders.length > 0) {
                    orderProperties.addAll(Arrays.asList(orders));
                }
            }
            orderCache.put(query.getClass(), orderProperties);
        }
        return orderCache.get(query.getClass()).stream().map(p -> new Order(p.column(), p.direction())).collect(Collectors.toList());
    }

    protected boolean isExpressionSupportIterableValue(Expression expression) {
        return expression.equals(Expression.IN) || expression.equals(Expression.NOT_IN);
    }
}
